package com.hs.srm.tools;

import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author ych
 * @description 文件下载工具
 * @date 2019-7-3
 */
public class FileUtils {

    /**
     * @param response response
     * @param request  request
     * @param filePath 文件路径（含文件名）
     * @param zipName  压缩包名称（不包含后缀名）
     * @description 多文件打包下载
     */
    public static void zipDownload(String[] filePath, String zipName, HttpServletRequest request,
                                   HttpServletResponse response) throws IOException {
        File[] files = new File[filePath.length];
        for (int i = 0; i < filePath.length; i++) {
            files[i] = new File(filePath[i]);
        }
        zipDownload(files, zipName, request, response);
    }

    /**
     * @param response response
     * @param request  request
     * @param files    文件对象
     * @param zipName  压缩包名称（不包含后缀名）
     * @description 多文件打包下载
     */
    public static void zipDownload(File[] files, String zipName, HttpServletRequest request,
                                   HttpServletResponse response) throws IOException {
        zipName += ".zip";
        response.reset();
        // 浏览器设置，防止下载乱码
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            // IE浏览器处理
            zipName = java.net.URLEncoder.encode(zipName, "UTF-8");
        } else {
            // 非IE浏览器的处理
            zipName = new String(zipName.getBytes("UTF-8"), "ISO-8859-1");
        }
        response.setContentType("APPLICATION/OCTET-STREAM;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + zipName);
        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
        zipFile(files, zos);
        zos.flush();
        zos.close();
    }

    private static void zipFile(File[] subs, ZipOutputStream zos) throws IOException {
        for (int i = 0; i < subs.length; i++) {
            File f = subs[i];
            zos.putNextEntry(new ZipEntry(f.getName()));
            FileInputStream fis = new FileInputStream(f);
            byte[] buffer = new byte[1024];
            int r = 0;
            while ((r = fis.read(buffer)) != -1) {
                zos.write(buffer, 0, r);
            }
            fis.close();
        }
    }

    /**
     * @param request  request
     * @param response response
     * @param filePath 文件路径（含文件名）
     * @description 单文件下载
     */
    public static void fileDownload(String filePath, HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        fileDownload(new File(filePath), request, response);
    }

    /**
     * @param request  request
     * @param response response
     * @param file     文件对象
     * @description 单文件下载
     */
    public static void fileDownload(File file, HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("APPLICATION/OCTET-STREAM;charset=utf-8");
        String fileName = file.getName();
        // 浏览器设置，防止下载乱码
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            // IE浏览器处理
            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
        } else {
            // 非IE浏览器的处理
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
        }
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        // 获取文件输入流
        FileInputStream in = new FileInputStream(file);
        int len = 0;
        byte[] buffer = new byte[1024];
        OutputStream out = response.getOutputStream();
        while ((len = in.read(buffer)) > 0) {
            // 将缓冲区的数据输出到客户端浏览器
            out.write(buffer, 0, len);
        }
        out.flush();
        in.close();
        out.close();
    }

    /**
     * 文件上传
     *
     * @param fileDirs      文件保存路径（不包含文件名，/aaa/bbb/ccc/）
     * @param fileName      文件名(包含扩展名)
     * @param multipartFile
     * @return
     */
    public static boolean fileUpload(String fileDirs, String fileName, MultipartFile multipartFile) {
        File saveFile = createDirOrFile(fileDirs, fileName);
        InputStream in = null;
        OutputStream os = null;
        try {
            in = multipartFile.getInputStream();
            os = new FileOutputStream(saveFile);
            byte[] buffer = new byte[4096];
            int n = 0;
            while ((n = in.read(buffer, 0, 4096)) != -1) {
                os.write(buffer, 0, n);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * 文件上传
     *
     * @param fileDirs 文件保存路径（不包含文件名，/aaa/bbb/ccc/）
     * @param fileName 文件名(包含扩展名)
     * @param part
     * @return
     * @throws IOException
     */
    public static boolean fileUpload(String fileDirs, String fileName, Part part) throws IOException {
        createDirOrFile(fileDirs, fileName);
        part.write(fileDirs + fileName);
        return true;
    }

    /**
     * 创建文件路径或文件
     *
     * @param fileDirs 文件保存路径（不包含文件名，/aaa/bbb/ccc/）
     * @param fileName 文件名(包含扩展名)
     * @return 保存文件对象
     */
    private static File createDirOrFile(String fileDirs, String fileName) {
        File fileDir = new File(fileDirs);
        // 路径最后不是’/'结束
        if (fileDirs.lastIndexOf("/") != (fileDirs.length() - 1)) {
            fileDirs += "/";
        }
        File saveFile = new File(fileDirs + fileName);
        // 文件夹不存在则创建
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        // 文件不存在则创建
        if (!saveFile.exists()) {
            try {
                saveFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return saveFile;
    }

    /**
     * pdf/image 在线预览
     *
     * @param response
     * @param file
     * @throws IOException
     */
    public static void viewFile(HttpServletResponse response, File file) throws IOException {
        response.reset();
        URL u = new URL("file:///" + file.getAbsolutePath());
        response.setContentType(u.openConnection().getContentType());
        response.setHeader("Content-Disposition", "inline; filename=" + file.getName());
        FileInputStream fileInputStream = new FileInputStream(file);
        OutputStream outputStream = response.getOutputStream();
        IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);
    }

    /**
     * 添加时间后缀
     *
     * @param fileName 文件名
     * @return
     */
    public static String addDateTimeSuffix(String fileName) {
        return addDateTimeSuffix(fileName, "_yyyyMMddHHmmss");
    }

    /**
     * 添加时间后缀
     *
     * @param fileName 文件名
     * @param pattern  后缀格式
     * @return
     */
    public static String addDateTimeSuffix(String fileName, String pattern) {
        String StrDate = new SimpleDateFormat(pattern).format(new Date());
        String newFileName = fileName.substring(0, fileName.lastIndexOf(".")) + StrDate + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
        return newFileName;
    }
}
